package com.harmonk.firstscene.constants

import com.harmonk.firstscene.db.entity.Road
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import kotlin.math.abs

/**
 * 工具类，包含各种实用工具方法
 */
object Utils {

    /**
     * 时间格式化工具
     * 根据传入的timestamp和格式要求，输出不同的时间格式
     */
    object TimeFormatter {
        private const val MINUTE_MILLIS = 60 * 1000
        private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
        private const val DAY_MILLIS = 24 * HOUR_MILLIS

        /**
         * 输出时分格式 HH:mm
         */
        fun formatHourMinute(timestamp: Long): String {
            val sdf = SimpleDateFormat("HH:mm", Locale.getDefault())
            return sdf.format(Date(timestamp))
        }

        /**
         * 输出今天加时分格式 今天 HH:mm
         */
        fun formatTodayWithHourMinute(timestamp: Long): String {
            val sdf = SimpleDateFormat("'今天' HH:mm", Locale.getDefault())
            return sdf.format(Date(timestamp))
        }

        /**
         * 输出月日加时分格式 MM-dd HH:mm
         */
        fun formatMonthDayWithHourMinute(timestamp: Long): String {
            val sdf = SimpleDateFormat("MM月dd日 HH:mm", Locale.getDefault())
            return sdf.format(Date(timestamp))
        }

        /**
         * 输出年月日加时分格式 yyyy-MM-dd HH:mm
         */
        fun formatYearMonthDayWithHourMinute(timestamp: Long): String {
            val sdf = SimpleDateFormat("yyyy年MM月dd日 HH:mm", Locale.getDefault())
            return sdf.format(Date(timestamp))
        }

        /**
         * 自动格式化时间
         * 今天就输出今天加时分，非今天但在今年则输出月日加时分，非今年则输出年月日加时分
         */
        fun autoFormat(timestamp: Long): String {
            val now = Calendar.getInstance()
            val target = Calendar.getInstance().apply { timeInMillis = timestamp }

            return when {
                // 同一年且同一天
                now.get(Calendar.YEAR) == target.get(Calendar.YEAR) &&
                        now.get(Calendar.DAY_OF_YEAR) == target.get(Calendar.DAY_OF_YEAR) -> {
                    formatTodayWithHourMinute(timestamp)
                }
                // 同一年但不是同一天
                now.get(Calendar.YEAR) == target.get(Calendar.YEAR) -> {
                    formatMonthDayWithHourMinute(timestamp)
                }
                // 不同年
                else -> {
                    formatYearMonthDayWithHourMinute(timestamp)
                }
            }
        }
    }

    /**
     * 身份证号码校验工具
     */
    object IdCardValidator {
        /**
         * 验证18位身份证号码是否合法
         *
         * @param idCard 18位身份证号码
         * @return 是否合法
         */
        fun isValidIdCard(idCard: String): Boolean {
            // 基本格式检查
            if (idCard.length != 18) return false

            // 检查前17位是否都是数字
            val front17 = idCard.substring(0, 17)
            if (!front17.matches(Regex("\\d{17}"))) return false

            // 检查最后一位是否是数字或X
            val lastChar = idCard[17]
            if (!(lastChar.isDigit() || lastChar == 'X' || lastChar == 'x')) return false

            // 验证地区码（前两位）
            val areaCode = idCard.substring(0, 2).toIntOrNull() ?: return false
            if (areaCode !in 11..82) return false // 简化的地区码验证

            // 验证出生日期（第7-14位）
            val birthStr = idCard.substring(6, 14)
            val year = birthStr.substring(0, 4).toIntOrNull() ?: return false
            val month = birthStr.substring(4, 6).toIntOrNull() ?: return false
            val day = birthStr.substring(6, 8).toIntOrNull() ?: return false

            if (month !in 1..12) return false
            if (day !in 1..31) return false

            // 验证校验码
            return validateCheckCode(idCard)
        }

        /**
         * 验证身份证校验码
         */
        private fun validateCheckCode(idCard: String): Boolean {
            val weight = intArrayOf(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
            val validate = charArrayOf('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')

            var sum = 0
            for (i in 0..16) {
                val num = idCard[i].toString().toIntOrNull() ?: return false
                sum += num * weight[i]
            }

            val mod = sum % 11
            val checkCode = validate[mod]
            val lastChar = idCard[17].uppercaseChar()

            return checkCode == lastChar
        }
    }

    /**
     * 经纬度格式化工具
     */
    object CoordinateFormatter {
        /**
         * 格式化经度，输出带有中文前缀和度分秒符号的字符串
         *
         * @param longitude 经度数值
         * @return 格式化后的字符串，如"东经120°30′45″"
         */
        fun formatLongitude(longitude: Double): String {
            val prefix = if (longitude >= 0) "东经" else "西经"
            return prefix + formatDegree(abs(longitude))
        }

        /**
         * 格式化纬度，输出带有中文前缀和度分秒符号的字符串
         *
         * @param latitude 纬度数值
         * @return 格式化后的字符串，如"北纬28°44′26″"
         */
        fun formatLatitude(latitude: Double): String {
            val prefix = if (latitude >= 0) "北纬" else "南纬"
            return prefix + formatDegree(abs(latitude))
        }

        /**
         * 将十进制度数转换为度分秒格式
         *
         * @param degree 十进制度数
         * @return 度分秒格式字符串，如"28°44′26″"
         */
        private fun formatDegree(degree: Double): String {
            val degrees = degree.toInt()
            val minutes = ((degree - degrees) * 60).toInt()
            val seconds = (((degree - degrees) * 60 - minutes) * 60).toInt()

            return "${degrees}°${minutes}′${seconds}″"
        }
    }

    fun locationFormat(
        road: Road?,
        direction: Int,
        isMainLine: Boolean,
        kilometer: Int,
        meter: Int,
        location: String
    ): String {
        val roadStr = if (road != null) "${road.name}${if (direction == 0) road.upDirection else road.downDirection}" else ""
        val locationStr = if (isMainLine) {kilometer.toString() + "公里" + meter.toString() + "米"} else location
        return roadStr + locationStr
    }
}